<?php 
namespace froyo\cherry\Db;
use froyo\cherry\Base\BaseObject;
use froyo\cherry\Base\Cherry;
class Connection extends BaseObject{
	public $connectId = null;
	public $database;
	protected $dbconfig;
	protected $dbdns;
	protected $pdoparams = [];
	protected $reconnecttimes = 0;
	protected $charset = 'utf8';
	const MAX_TRY_TIME = 2;


	public function setDbConfig($config=[]){
		$this->dbconfig = array_merge([
			'host'=>'127.0.0.1',
			'port'=>'3306',
			'username'=>'',
			'password'=>'',
			'params'=>[

			],
			'database'=>'',
			'type'=>'mysql',
		],Cherry::$app->getComment('database')->getConfig(),$config);
		$this->pdoparams = $this->dbconfig['params'];
		$this->pdoparams = array_merge([
			\PDO::ATTR_ERRMODE=>\PDO::ERRMODE_EXCEPTION

		],$this->pdoparams);
		$dns = $this->dbconfig['type'].
			 ':dbname='.$this->dbconfig['database'].
			 ';host='.$this->dbconfig['host'].';'.
			 'port='.$this->dbconfig['port'];

		$this->setDbdns($dns);
		return $this;
	}

	public function setDbdns($dns)
	{
		$this->dbdns = $dns;
		return $this;
	}

	//连接数据库
	public function connect($reconnect=false){
		if(!$reconnect || !$this->database)
		{
			try {

			 	$this->database = new \PDO($this->dbdns, $this->dbconfig['username'], $this->dbconfig['password'],$this->pdoparams); 
			 	$this->database->exec('SET NAMES ' . $this->database->quote($this->charset));

			 	$this->reconnecttimes = 0;
			}
			catch(\PDOException $e) 
			{

				if($this->reconnecttimes>self::MAX_TRY_TIME)
				{
					throw $e;
				}
				else
				{
					$this->reconnecttimes++;
					return $this->connect($reconnect);
				}
			}
		}
	}


	function __call($method,$params){
		$this->connect();

		if(is_callable([$this->database,$method]))
		{

			return $this->callpdomethod($method,$params,0);
		}
		throw new \Exception($method.' on Connection Not Exist', 1);
		
	}

	protected function callpdomethod($method,$params,$trytimes = 0)
	{
		$this->connect();
		try{
			return call_user_func_array([$this->database,$method], $params);
		}catch(\Exception $e){
			if($trytimes>self::MAX_TRY_TIME)
			{
				throw $e;
			}
			$this->free();
			return $this->callpdomethod($method,$params,++$trytimes);
		}
	}


	//释放数据库
	public function free(){
		$this->database = null;
	}

    public function __destruct()
    {
        $this->database = null;
    }

    public function getPdo(){

    	return $this->database;
    }
}